<?php

namespace app\system\controller\finance;

use app\common\controller\System;
use app\system\controller\goods\ZipArchive;
use ba\Filesystem;
use hehe\Numeral;
use hehe\Str;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use think\facade\Db;

/**
 * 商品管理
 */
class Cost extends System {
    /**
     * Goods模型对象
     * @var object
     * @phpstan-var \app\admin\model\goods\Goods
     */
    protected object $model;

    protected string|array $defaultSortField = 'id,desc';

    protected array|string $preExcludeFields = ['id', 'create_time'];

    protected string|array $quickSearchField = [];

    public function initialize(): void {
        parent::initialize();
        $this->model = new \app\system\model\finance\Cost;
    }
    public function add(): void
    {
        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Parameter %s can not be empty', ['']));
            }

            $data = $this->excludeFields($data);
            if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                $data[$this->dataLimitField] = $this->auth->id;
            }

            $data['trade_time'] = empty($data['trade_time']) ? null : strtotime($data['trade_time']);


            $admin = db::name('admin')->where(['id' => $data['admin_id']])->find();
            if(empty($data['money']) || $data['money'] < 0) $this->error('请输入正确的金额');
            $admin['amount'] = empty($admin['amount']) ? 0 : $admin['amount'];
            if($data['sz'] == '支出') {
                $data['expenditure'] = $data['money'] * 100;
                $data['amount'] = $admin['amount'] - $data['expenditure'];
            }else{ // 收入
                $data['income'] = $data['money'] * 100;
                $data['amount'] =  $admin['amount'] + $data['income'];
            }

            unset($data['money']);

            $result = false;
            $this->model->startTrans();
            try {
                // 模型验证
                if ($this->modelValidate) {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    if (class_exists($validate)) {
                        $validate = new $validate;
                        if ($this->modelSceneValidate) $validate->scene('add');
                        $validate->check($data);
                    }
                }
                db::name('admin')->where(['id' => $admin['id']])->update(['amount' => $data['amount']]);
                $data['filter_id'] = $this->filter['id'];
                $result = $this->model->save($data);
                $this->model->commit();
            } catch (Throwable $e) {
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Added successfully'));
            } else {
                $this->error(__('No rows were added'));
            }
        }

        $this->error(__('Parameter error'));
    }

    /**
     * 编辑
     * @throws Throwable
     */
    public function edit(): void
    {
        $id  = $this->request->param($this->model->getPk());
        $row = $this->model->find($id);
        if (!$row) {
            $this->error(__('Record not found'));
        }

        $dataLimitAdminIds = $this->getDataLimitAdminIds();
        if ($dataLimitAdminIds && !in_array($row[$this->dataLimitField], $dataLimitAdminIds)) {
            $this->error(__('You have no permission'));
        }

        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Parameter %s can not be empty', ['']));
            }

            $data   = $this->excludeFields($data);

            $data['trade_time'] = empty($data['trade_time']) ? null : strtotime($data['trade_time']);

            $money = $data['money'] * 100;
            unset($data['money']);


//            print_r($data); die;


            $result = false;
            $this->model->startTrans();
            try {
                // 模型验证
                if ($this->modelValidate) {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    if (class_exists($validate)) {
                        $validate = new $validate;
                        if ($this->modelSceneValidate) $validate->scene('edit');
                        $validate->check($data);
                    }
                }


                if($data['sz'] == '收入'){
                    $data['income'] = $money;
                    if($money > $row['income']){
                        $diff = $money - $row['income'];
                        $data['amount'] -= $diff;
                        db::name('admin')->where(['id' => $row['admin_id']])->inc('amount', $diff)->update();
                    }
                    if($money < $row['income']){
                        $diff = $row['income'] - $money;
                        $data['amount'] += $diff;
                        db::name('admin')->where(['id' => $row['admin_id']])->dec('amount', $diff)->update();
                    }
                }
                if($data['sz'] == '支出'){
                    $data['expenditure'] = $money;
                    if($money > $row['expenditure']){
                        $diff = $money - $row['expenditure'];
                        $data['amount'] -= $diff;
                        db::name('admin')->where(['id' => $row['admin_id']])->dec('amount', $diff)->update();
                    }
                    if($money < $row['expenditure']){
                        $diff = $row['expenditure'] - $money;
                        $data['amount'] += $diff;
                        db::name('admin')->where(['id' => $row['admin_id']])->inc('amount', $diff)->update();
                    }
                }




                $result = $row->save($data);
                $this->model->commit();
            } catch (Throwable $e) {
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Update successful'));
            } else {
                $this->error(__('No rows updated'));
            }
        }

        $row['money'] = $row['income'] > 0 ? $row['income'] : $row['expenditure'];
        $row['money'] /= 100;
        $row['trade_time'] = empty($row['trade_time']) ? null : date('Y-m-d H:i:s', $row['trade_time']);

        $this->success('', [
            'row' => $row
        ]);
    }


    public function del(array $ids = []): void
    {
        if (!$this->request->isDelete() || !$ids) {
            $this->error(__('Parameter error'));
        }

        $where             = [];
        $dataLimitAdminIds = $this->getDataLimitAdminIds();
        if ($dataLimitAdminIds) {
            $where[] = [$this->dataLimitField, 'in', $dataLimitAdminIds];
        }

        $pk      = $this->model->getPk();
        $where[] = [$pk, 'in', $ids];

        $count = 0;
        $data  = $this->model->where($where)->select();
        $this->model->startTrans();
        try {
            foreach ($data as $v) {
                $count += $v->delete();
//                echo $v->income;die;
                if($v->income > 0){ // 收入
                    db::name('admin')->where(['id' => $v->admin_id])->dec('amount', $v->income)->update();
                } else { // 支出
                    db::name('admin')->where(['id' => $v->admin_id])->inc('amount', $v->expenditure)->update();
                }


            }
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success(__('Deleted successfully'));
        } else {
            $this->error(__('No rows were deleted'));
        }
    }

    public function getAdminInfo(){
        $param = $this->request->param();
        $result = db::name('admin')->where(['id' => $param['id']])->find();
        $result['amount'] = empty($result['amount']) ? 0 : Numeral::numberFormat($result['amount'] / 100);
        $this->success('', $result);
    }

    public function index(): void {
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->param('select')) {
            $this->select();
        }
        list($where, $alias, $limit, $order) = $this->queryBuilder();


        $res = $this->model->with(['admin'])->where($where)->where(['filter_id' => $this->filter['id']]);

        $param = $this->request->param();

        if(!empty($param['year'])){
            $res->whereYear('trade_time', $param['year']);
        }
        if(!empty($param['month'])){
            if(empty($param['year'])) $this->error(__('请选择年份'));
            $month = $param['month'] < 10 ? '0' . $param['month'] : $param['month'];
            $res->whereMonth('trade_time', $param['year'] . '-' . $month);
        }
        if(!empty($param['type'])){
            $res->where(['type' => $param['type']]);
        }
        if(!empty($param['admin_id'])){
            $res->where(['admin_id' => $param['admin_id']]);
        }

        $res = $res->order($order)->paginate($limit);

        $list = $res->items();

        foreach($list as $key => $val){
            $list[$key]['amount'] = empty($val['amount']) ? 0 : Numeral::numberFormat($val['amount'] / 100);
            $list[$key]['expenditure'] = empty($val['expenditure']) ? 0 : Numeral::numberFormat($val['expenditure'] / 100);
            $list[$key]['income'] = empty($val['income']) ? 0 : Numeral::numberFormat($val['income'] / 100);
            $type = $val['type'];
            if($type == '办公室_仓库') {
                $list[$key]['type'] = __('办公室') . '&' . __('仓库');
            }else{
                $list[$key]['type'] = empty($val['type']) ? '' : __($type);
            }

        }



        $this->success('', [
            'list' => $res->items(),
            'total' => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }

    public function exportData(): void {
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->param('select')) {
            $this->select();
        }
        list($where, $alias, $limit, $order) = $this->queryBuilder();


        $res = $this->model->with(['admin'])->where($where);

        $param = $this->request->param();

        if(!empty($param['year'])){
            $res->whereYear('trade_time', $param['year']);
        }
        if(!empty($param['month'])){
            if(empty($param['year'])) $this->error(__('请选择年份'));
            $month = $param['month'] < 10 ? '0' . $param['month'] : $param['month'];
            $res->whereMonth('trade_time', $param['year'] . '-' . $month);
        }
        if(!empty($param['type'])){
            $res->where(['type' => $param['type']]);
        }
        if(!empty($param['admin_id'])){
            $res->where(['admin_id' => $param['admin_id']]);
        }

        $list = $res->order($order)->select();

        $dir = Filesystem::fsFit(public_path() . 'storage\\finance_cost\\');
        if(!file_exists($dir)){
            Filesystem::mkdir($dir);
        }

        $filename = '费用管理 - ' . date('ymdHis') . '.xlsx';
        $filepath = $dir . $filename;


        $spreadsheet = new Spreadsheet(); // 创建文件
        $spreadsheet->getDefaultStyle()->getFont()->setName('宋体'); // 设置默认字体
        $spreadsheet->getDefaultStyle()->getAlignment()->setVertical(Alignment::VERTICAL_CENTER); // 全局垂直居中

        $sheet = $spreadsheet->getActiveSheet(); // 选择第一个选项卡
        $sheet->setTitle('PACKING LIST'); //设置worksheet名称
        $sheet->getDefaultRowDimension()->setRowHeight(22); // 设置默认行高
        $sheet->getColumnDimension('A')->setWidth(18); // 设置列宽
        $sheet->getColumnDimension('B')->setWidth(12);
        $sheet->getColumnDimension('C')->setWidth(12);
        $sheet->getColumnDimension('D')->setWidth(12);
        $sheet->getColumnDimension('E')->setWidth(20);
        $sheet->getColumnDimension('F')->setWidth(30);
        $sheet->getColumnDimension('G')->setWidth(20);

        $sheet->setCellValue('A1', __('账户'));
        $sheet->setCellValue('B1', __('余额'));
        $sheet->setCellValue('C1', __('收入'));
        $sheet->setCellValue('D1', __('支出'));
        $sheet->setCellValue('E1', __('类型'));
        $sheet->setCellValue('F1', __('内容'));
        $sheet->setCellValue('G1', __('时间'));
        $sheet->getStyle("A1:G1")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // 水平居中
        $i = 2;
        foreach($list as $key => $val){
            $amount = empty($val['amount']) ? 0 : Numeral::numberFormat($val['amount'] / 100);
            $expenditure = empty($val['expenditure']) ? 0 : Numeral::numberFormat($val['expenditure'] / 100);
            $income = empty($val['income']) ? 0 : Numeral::numberFormat($val['income'] / 100);
            $trade_time = empty($val['trade_time']) ? null : date('Y-m-d', $val['trade_time']);
            $admin_name = empty($val['admin']['name']) ? $val['admin']['username'] : $val['admin']['name'];
            $sheet->setCellValue('A' . $i, $admin_name);
            $sheet->setCellValue('B' . $i, $val['admin']['amount']);
            $sheet->setCellValue('C' . $i, $income);
            $sheet->setCellValue('D' . $i, $expenditure);
            $sheet->setCellValue('E' . $i, $val['type']);
            $sheet->setCellValue('F' . $i, $val['note']);
            $sheet->setCellValue('G' . $i, $trade_time);
            $sheet->getStyle("A{$i}:G{$i}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // 水平居中
            $i++;
        }

        $writer = IOFactory::createWriter($spreadsheet, 'Xls'); // 写入数据
        $writer->save($filepath); // 保存文件


        $file_url = '/storage/finance_cost/' . $filename;

        $this->success('', $file_url);



        $sheet->getRowDimension(1)->setRowHeight(38); // 设置行高
        $sheet->getStyle('A1')->getFont()->setSize(16)->setBold(true); //字体大小
        $sheet->getStyle('A1')->getFont()->setBold(true); //字体加粗
        $sheet->mergeCells( 'A1:F1'); // 合并单元格
        $sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // 水平居中
        $sheet->getStyle('A1:F1')->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setARGB('F2F2F2'); // 设置背景色
        $sheet->getStyle('A1:F1')->getBorders()->getBottom()->setBorderStyle(Border::BORDER_THIN); //设置下边框细

        $sheet->setCellValue('A2', 'PACKING LIST');
        $sheet->getRowDimension(2)->setRowHeight(30);
        $sheet->getStyle('A2')->getFont()->setSize(16)->setBold(true);
        $sheet->getStyle('A2')->getFont()->setBold(true);
        $sheet->mergeCells( 'A2:F2');
        $sheet->getStyle('A2')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
        $sheet->getStyle('A2:F2')->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setARGB('F2F2F2');









    }



    public function getAdmin(){
        $admin = db::name('admin')->field('id, username, nickname, name')->where(['outstation_id' => 0, 'filter_id' => $this->filter['id']])->where("username != 'admin'")->order('id asc')->select();
        $this->success('', $admin);
    }




}